/*******************************************************************************
* Project: QSAR(Cute Software Architecture) 
*
* Copyright: Copyright(C) 2024 by YuetingBen, All Rights Reserved
*
* File name: E2EP01.c
*
* Brief: ;
*
* Author: Yueting.Ben
*
* Module: E2E
*
*******************************************************************************/

/** HEADER FILES **/
#include "E2EP01.h"


/** MACRO DEFINITION **/


/** TYPEDEF DEFINITION **/


/** LOCAL DATA DECLARATION **/


/** GLOBAL DATA DECLARATION **/


/** LOCAL FUNCTION DECLARATION **/


/** GLOBAL FUNCTION DECLARATION **/


/** LOCAL DATA **/


/** GLOBAL DATA **/


/** LOCAL FUNCTION **/


/** GLOBAL FUNCTION **/

/*******************************************************************************
* -Name         E2E_P01Protect
* -Brief        Protects the array/buffer to be transmitted using the E2E profile 1. This includes 
*               checksum calculation, handling of counter and Data ID. 
* -Details      None
* -Param[in]    ConfigPtr: Pointer to static configuration
* -Param[inout] StatePtr: Pointer to port/data communication state
* -Param[inout] DataPtr: Pointer to Data to be transmitted
* -Param[out]   versioninfo: Pointer to the version information of this module
* -Return       E2E_E_INPUTERR_NULL 
*               E2E_E_INPUTERR_WRONG 
*               E2E_E_INTERR 
*               E2E_E_OK           
*******************************************************************************/
Std_ReturnType E2E_P01Protect( 
    const E2E_P01ConfigType* ConfigPtr, 
    E2E_P01ProtectStateType* StatePtr, 
    uint8* DataPtr 
)
{
    Std_ReturnType retVal = E2E_E_OK;
    uint8 crc8 = 0x00;
    uint8 idDataBuffer[2] = {0x00};

    switch(ConfigPtr->DataIDMode)
    {
        case E2E_P01_DATAID_BOTH:
        {
            idDataBuffer[0] = (uint8)(ConfigPtr->DataID >> 8u);
            idDataBuffer[1] = (uint8)ConfigPtr->DataID;
            Crc_CalculateCrc8((uint8*)idDataBuffer, 2u, (uint8*)&crc8);
            break;
        }
    }
    DataPtr[ConfigPtr->CounterOffset / 8u] = DataPtr[ConfigPtr->CounterOffset / 8u] & 0xF0; /* Clear counter data */
    DataPtr[ConfigPtr->CounterOffset / 8u] = DataPtr[ConfigPtr->CounterOffset / 8u] | (StatePtr->Counter & 0x0Fu);

    Crc_CalculateCrc8(DataPtr, ConfigPtr->DataLength, (uint8*)&crc8);

    DataPtr[ConfigPtr->CRCOffset / 8u] = crc8;
    StatePtr->Counter++;

    return(retVal);
}

/*******************************************************************************
* -Name         E2E_P01ProtectInit
* -Brief        Initializes the protection state
* -Details      None
* -Param[in]    None
* -Param[out]   StatePtr: Pointer to port/data communication state
* -Return       E2E_E_INPUTERR_NULL - null pointer passed 
*               E2E_E_OK          
*******************************************************************************/
Std_ReturnType E2E_P01ProtectInit( 
    E2E_P01ProtectStateType* StatePtr 
)
{
    
}

/*******************************************************************************
* -Name         E2E_P01Forward
* -Brief        Protects data which is forwarded by using the E2E profile 01. This includes 
*               checksum calculation, handling of counter and Data ID. Detected Errors of received 
*               message will be reconstruct on output data
* -Details      None
* -Param[in]    ConfigPtr: Pointer to static configuration
* -Param[in]    Checkstatus: E2E Status of the received message
* -Param[inout] StatePtr: Pointer to port/data communication state
* -Param[inout] DataPtr: Pointer to Data to be transmitted
* -Param[out]   StatePtr: Pointer to port/data communication state
* -Return       E2E_E_INPUTERR_NULL 
*               E2E_E_INPUTERR_WRONG 
*               E2E_E_INTERR 
*               E2E_E_OK          
*******************************************************************************/
Std_ReturnType E2E_P01Forward( 
    const E2E_P01ConfigType* ConfigPtr, 
    E2E_PCheckStatusType Checkstatus, 
    E2E_P01ProtectStateType* StatePtr, 
    uint8* DataPtr 
)
{
    
}

/*******************************************************************************
* -Name         E2E_P01Check
* -Brief        Checks the Data received using the E2E profile 1. This includes CRC calculation, handling of Counter and Data ID.
* -Details      None
* -Param[in]    Config: Pointer to static configuration
* -Param[in]    Data: Pointer to received data
* -Param[inout] State: Pointer to port/data communication state
* -Param[out]   None
* -Return       E2E_E_INPUTERR_NULL 
*               E2E_E_INPUTERR_WRONG 
*               E2E_E_INTERR 
*               E2E_E_OK          
*******************************************************************************/
Std_ReturnType E2E_P01Check( 
    const E2E_P01ConfigType* Config, 
    E2E_P01CheckStateType* State, 
    const uint8* Data
)
{
    Std_ReturnType retVal = E2E_E_INPUTERR_WRONG;
    uint8 crc8 = 0x00;
    uint8 idDataBuffer[2] = {0x00};

    switch(Config->DataIDMode)
    {
        case E2E_P01_DATAID_BOTH:
        {
            idDataBuffer[0] = (uint8)(Config->DataID >> 8u);
            idDataBuffer[1] = (uint8)Config->DataID;
            Crc_CalculateCrc8((uint8*)idDataBuffer, 2u, (uint8*)&crc8);
            break;
        }
    }

    Crc_CalculateCrc8((uint8*)Data, Config->DataLength, (uint8*)&crc8);
    
    /* Check counter */
    /* Check repeated counter  */
    if(State->LastValidCounter == (Data[Config->CounterOffset / 8u] & 0x0F))
    {
        State->Status = E2E_P01STATUS_OKSOMELOST;
        if(Config->MaxNoNewOrRepeatedData > State->NoNewOrRepeatedDataCounter)
        {
            State->NoNewOrRepeatedDataCounter++;
        }
        else
        {
            State->Status = E2E_P01STATUS_REPEATED;
        }
    }
    else if(State->MaxDeltaCounter < (((Data[Config->CounterOffset / 8u] & 0x0F + 0x10) - State->LastValidCounter) % 0x10))
    {
        State->Status = E2E_P01STATUS_OKSOMELOST;
        if(Config->SyncCounterInit > State->LostData)
        {
            State->LostData++;
        }
        else
        {
            State->Status = E2E_P01STATUS_WRONGSEQUENCE;
        }
    }
    /* Check CRC */
    else if(Data[Config->CRCOffset / 8u] != crc8)
    {
        
        State->Status = E2E_P01STATUS_OKSOMELOST;
        if(Config->SyncCounterInit > State->LostData)
        {
            State->LostData++;
        }
        else
        {
            State->Status = E2E_P01STATUS_WRONGCRC;
        }
    }
    else
    {
        State->LostData = 0u;
        State->NoNewOrRepeatedDataCounter = 0u;
        State->Status = E2E_P01STATUS_OK;
    }

    if((E2E_P01STATUS_OKSOMELOST == State->Status)
      || (E2E_P01STATUS_OK == State->Status))
    { 
        retVal = E2E_E_OK;
    }
    State->LastValidCounter = Data[Config->CounterOffset / 8u] & 0x0F;  

    return(retVal);
}

/*******************************************************************************
* -Name         E2E_P01CheckInit
* -Brief        Initializes the check state
* -Details      None
* -Param[in]    CNone
* -Param[out]   StatePtr: Pointer to port/data communication state
* -Return       E2E_E_INPUTERR_NULL - null pointer passed 
*               E2E_E_OK       
*******************************************************************************/
Std_ReturnType E2E_P01CheckInit( 
    E2E_P01CheckStateType* StatePtr 
) 
{
    
}

/*******************************************************************************
* -Name         E2E_P01MapStatusToSM
* -Brief        Initializes the check state
* -Details      The function maps the check status of Profile 1 to a generic check status, which can 
*               be used by E2E state machine check function. The E2E Profile 1 delivers a more 
*               fine-granular status, but this is not relevant for the E2E state machine. 
* -Param[in]    CheckReturn: Return value of the E2E_P01Check function
* -Param[in]    Status: Status determined by E2E_P01Check function
* -Param[in]    profileBehavior: FALSE: check has the legacy behavior, before R4.2 TRUE: 
*                                check behaves like new P4/P5/P6 profiles introduced in R4.2
* -Param[out]   StatePtr: Pointer to port/data communication state
* -Return       Profile-independent status of the reception on one single Data in one cycle      
*******************************************************************************/
E2E_PCheckStatusType E2E_P01MapStatusToSM( 
    Std_ReturnType CheckReturn, 
    E2E_P01CheckStatusType Status, 
    boolean profileBehavior 
)
{
    
}

